package com.aboverock.module.system.service.impl;

import com.aboverock.autoconfigure.properties.LocalUserProperties;
import com.aboverock.autoconfigure.util.JwtUtil;
import com.aboverock.common.enums.UserStatusEnum;
import com.aboverock.common.enums.UserTypeEnum;
import com.aboverock.core.shiro.util.ShiroHashEncryptUtil;
// import com.aboverock.datalake.exceptions.DatalakeDataParseException;
// import com.aboverock.datalake.exceptions.DatalakeRequestException;
// import com.aboverock.module.datalake.service.DatalakeService;
import com.aboverock.module.system.domain.SuperAdmin;
import com.aboverock.module.system.domain.User;
import com.aboverock.module.system.mapper.UserMapper;
import com.aboverock.module.system.service.UserRoleService;
import com.aboverock.module.system.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 服务实现类.
 * </p>
 *
 * @author Rock Wang
 * @since 2018-04-02
 */
@Service
@EnableConfigurationProperties(LocalUserProperties.class)
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    /** The super admin. */
    @Autowired
    private SuperAdmin superAdmin;

    // @Autowired
    // private DatalakeService datalakeService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private LocalUserProperties localUserProperties;

    @Override
    public boolean isSupportLocalUser() {
        return localUserProperties.isSupport();
    }

    @Override
    public User getADUserByLoginName(String loginName) {
        return this.getOne(new QueryWrapper<User>().eq("login_name", loginName).eq("type",
                UserTypeEnum.AD.getValue()));
    }

    @Override
    public User getLocalUserByLoginName(String loginName) {
        return this.getOne(new QueryWrapper<User>().eq("login_name", loginName).eq("type",
                UserTypeEnum.LOCAL.getValue()));
    }

    @Override
    public User getByLoginNameWithRoles(String loginName) {
        return baseMapper.getByLoginNameWithRoles(loginName);
    }

    @Override
    public User getCurrentUserWithRoles() {
        String loginName = JwtUtil.getLoginName();
        if (null == loginName) {
            return null;
        }

        User loginUser = this.getByLoginNameWithRoles(loginName);
        return loginUser;
    }

    @Override
    public List<User> getUsersWithRoles() {
        return baseMapper.getUsersWithRoles(null, null);
    }

    @Override
    public List<User> getUsersWithRoles(Long start, Long pageSize) {
        return baseMapper.getUsersWithRoles(start, pageSize);
    }

    @Override
    public List<User> fuzzyQueryByLoginName(String loginName) {
        List<User> users = this.list(new QueryWrapper<User>().like("login_name", loginName));
        return users;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<User> saveDataLakeEmpInfoToDb(List<User> users) throws SQLException {
        for (User user : users) {
            if (null == this.saveDataLakeEmpInfoToDb(user)) {
                throw new SQLException("save user[{}] failed", user.getLoginName());
            }
        }
        return users;
    }

    @Override
    public synchronized User saveDataLakeEmpInfoToDb(User user) {
        User oldUser = this.getADUserByLoginName(user.getLoginName());

        if (oldUser != null) {
            user.setId(oldUser.getId());
            user.setStatus(oldUser.getStatus());
            user.setVersion(oldUser.getVersion());
            this.updateById(user);
            return user;
        } else {
            user.setType(UserTypeEnum.AD.getValue());
            user.setStatus(UserStatusEnum.NORMAL.getValue());
            if (this.save(user)) {
                if (!userRoleService.addCommonRole(user.getId())) {
                    logger.warn("Data-Smart: 给用户{}添加通用角色失败", user.getLoginName());
                }
                return user;
            }
        }

        return null;
    }

    // @Override
    // public void updateFromDatalake() throws DatalakeRequestException, DatalakeDataParseException {
    //     List<User> users = list(null);
    //     for (User user : users) {
    //         User u = datalakeService.getUserByLoginName(user.getLoginName());
    //         if (u != null) {
    //             saveDataLakeEmpInfoToDb(u);
    //         }
    //     }
    // }

    @Override
    public boolean lockUsersByUserId(List<String> userIds) {
        Map<String, Object> params = new HashMap<>(2);
        params.put("userIds", userIds);
        params.put("status", UserStatusEnum.LOCKED.getValue());
        return baseMapper.updateUserStatusByUserId(params);
    }

    @Override
    public boolean unlockUsersByUserId(List<String> userIds) {
        Map<String, Object> params = new HashMap<>(2);
        params.put("userIds", userIds);
        params.put("status", UserStatusEnum.NORMAL.getValue());
        return baseMapper.updateUserStatusByUserId(params);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByIds(List<String> userIds) throws SQLException {
        try {
            removeByIds(userIds);
            userRoleService.removeByUserIds(userIds);
        } catch (Exception e) {
            throw new SQLException(e);
        }
    }

    @Override
    public boolean updateLocalUserPassword(User user) {
        user.setPassword(ShiroHashEncryptUtil.encrypt(user.getPassword()));
        return this.update(user, new UpdateWrapper<User>().eq("login_name", user.getLoginName())
                .eq("type", UserTypeEnum.LOCAL.getValue()));
    }

    @Override
    public User getByIdIgnoreLogicDelete(Serializable id) {
        return baseMapper.getByIdIgnoreLogicDelete(id);
    }

    @Override
    @Deprecated
    public boolean isSuperAdmin(User user) {
        return superAdmin.getName().equalsIgnoreCase(user.getLoginName());
    }

    @Override
    @Deprecated
    public boolean isSuperAdminName(String loginName) {
        return superAdmin.getName().equalsIgnoreCase(loginName);
    }

}
